package com.computer.fundamentals.datastructure;

import com.computer.fundamentals.datastructure.node.SingleCircularLinkedNode;
import com.computer.util.Constant;
import com.computer.util.UniversalMethod;

public class SingleCircularLinkedList {

    // 头部哨兵
    public SingleCircularLinkedNode head;

    // 尾部节点
    public SingleCircularLinkedNode tail;

    // 链表长度，伪概念，正确的来讲应该叫周长
    public int size;

    public SingleCircularLinkedList(SingleCircularLinkedNode head_, SingleCircularLinkedNode tail_) {
        this.head = head_;
        this.tail = tail_;
    }

    /**
     * 头插法
     */
    public void addFirst(int val_) {
        SingleCircularLinkedNode node = new SingleCircularLinkedNode(val_);
        if (size == 0) {
            tail = node;
        }
        node.next = head.next;
        head.next = node;
        tail.next = node;
        size++;
    }

    /**
     * 头删法
     */
    public void removeFirst() {
        if (size <= 0) {
            throw new RuntimeException(Constant.LINKED_LIST_LENGTH_ZERO);
        }
        head.next = head.next.next;
        tail.next = head.next;
        size--;
    }

    /**
     * 向位置i插入节点，i从1开始
     */
    public void insert(int idx, int val_) {
        if (idx > size || idx < 1) {
            throw new RuntimeException(Constant.LINKED_LIST_INDEX_OUT_OF_RANGE);
        }
        if (idx == 1) {
            addFirst(val_);
            return;
        }
        SingleCircularLinkedNode cur = head;
        while (idx > 1) {
            cur = cur.next;
            idx--;
        }
        SingleCircularLinkedNode newNode = new SingleCircularLinkedNode(val_);
        newNode.next = cur.next;
        cur.next = newNode;
        size++;
    }

    /**
     * 删除位置i的节点，i从1开始
     */
    public void remove(int idx) {
        if (idx > size || idx < 1) {
            throw new RuntimeException(Constant.LINKED_LIST_INDEX_OUT_OF_RANGE);
        }
        if (idx == 1) {
            removeFirst();
            return;
        }
        SingleCircularLinkedNode cur = head;
        int idxCopy = idx;
        while (idxCopy > 1) {
            cur = cur.next;
            idxCopy--;
        }
        if (idx == size) {
            this.tail.next = null;
            cur.next = cur.next.next;
            cur.next = head.next;
            this.tail = cur;
        }else {
            cur.next = cur.next.next;
        }
        size--;
    }

    /**
     * 打印链表,循环两次便于验证
     */
    public void printLinked() {
        SingleCircularLinkedNode cur = head.next;
        int length = this.size * 2;
        while (length > 0) {
            if (length != 1) {
                System.out.print(cur.val + Constant.SINGLE_LINKED_LIST_SPLIT_SIGNAL);
            }
            else {
                System.out.print(cur.val);
            }
            cur = cur.next;
            length--;
        }
    }

    /**
     * 测试
     */
    public static void main(String[] args) {

        SingleCircularLinkedList singleCircularLinkedList =
                UniversalMethod.createSingleCircularLinkedList(Constant.DEFAULT_LINKED_LIST_LENGTH);

        System.out.println("-------------------完整链表-------------------");
        singleCircularLinkedList.printLinked();
        System.out.println("\n");

        System.out.println("-------------------头插法-------------------");
        singleCircularLinkedList.addFirst(-1);
        singleCircularLinkedList.printLinked();
        System.out.println("\n");

        System.out.println("-------------------删除头部节点-------------------");
        singleCircularLinkedList.removeFirst();
        singleCircularLinkedList.printLinked();
        System.out.println("\n");

        System.out.println("-------------------向链表某一个位置插入节点-------------------");
        singleCircularLinkedList.insert(5, 100);
        singleCircularLinkedList.printLinked();
        System.out.println("\n");

        System.out.println("-------------------删除某一个位置的节点-------------------");
        singleCircularLinkedList.remove(5);
        singleCircularLinkedList.printLinked();

    }
}